package com.zd.kids.ui.fragment;

import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.blankj.utilcode.util.FileUtils;
import com.hyy.libray.common.BaseUtils;
import com.hyy.libray.presenter.IBasePresenter;
import com.hyy.libray.ui.fragment.BaseFragment;
import com.zd.kids.DataBean.BaseDataBean;
import com.zd.kids.DataBean.TestTrainDataBean;
import com.zd.kids.DataBean.TestTrainWordResultDataBean;
import com.zd.kids.R;
import com.zd.kids.common.GlideUtil;
import com.zd.kids.common.ToastUtils;
import com.zd.kids.net.CustomApi;
import com.zd.kids.net.CustomObserver;
import com.zd.kids.net.HttpMethod;
import com.zd.kids.ui.view.AudioView;
import com.zd.kids.ui.view.TestWordRecordPopupWindow;
import com.zd.kids.ui.view.WaveView;
import com.zlw.main.recorderlib.RecordManager;
import com.zlw.main.recorderlib.recorder.RecordHelper;
import com.zlw.main.recorderlib.recorder.listener.RecordDataListener;
import com.zlw.main.recorderlib.recorder.listener.RecordResultListener;
import com.zlw.main.recorderlib.recorder.listener.RecordSoundSizeListener;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

import androidx.cardview.widget.CardView;
import butterknife.BindView;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;
import io.reactivex.functions.Predicate;
import io.reactivex.schedulers.Schedulers;

public class TestTrainFragment extends BaseFragment {

    @BindView(R.id.progress_bar)
    ProgressBar progressBar;

    @BindView(R.id.img_recording)
    ImageView imgRecording;

    @BindView(R.id.tv_words)
    TextView tvWords;

    @BindView(R.id.tv_py)
    TextView tvPy;

    @BindView(R.id.record_pb)
    ProgressBar recordBb;

    @BindView(R.id.card_content)
    CardView cardContent;

    @BindView(R.id.wave_view)
    WaveView waveView;

    public TestTrainFragment(List<TestTrainDataBean> itemDatas) {

        this.testTrainDataBeans = itemDatas;
    }

    private String mGroupid;

    private String mCategoryid;

    private boolean isAiRecord;

    private String mUnitId;
    private String mQuesName;

    RecordManager recordManager;

    /**
     * ai测试，上传文件数量
     */
    private int mAiTestUploadNum;

    /**
     * 获取布局文件地址
     */
    @Override
    public int getLayoutResId() {
        return R.layout.fragment_train_test;
    }

    /**
     * 初始化布局
     *
     * @param view
     */
    @Override
    public void initView(View view) {

    }

    private int getRandom() {
        Random random = new Random();
        int randomInt = random.nextInt(10);
        return randomInt;
    }

    /**
     * 初始化数据
     */
    @Override
    public void initData() {
        recordManager = RecordManager.getInstance();

        recordManager.setRecordDataListener(new RecordDataListener() {
            @Override
            public void onData(byte[] data) {
                waveView.addData(data);
            }
        });
        recordManager.setRecordSoundSizeListener(new RecordSoundSizeListener() {
            @Override
            public void onSoundSize(int soundSize) {

            }
        });

        recordManager.setRecordResultListener(new RecordResultListener() {
            @Override
            public void onResult(File result) {

                intervalStartWordTest();

                String fileName = result.getName().replace(".wav", "");

                String[] fileNameArry = fileName.split("_");

                uploadRecordFile(result.getAbsolutePath(), fileNameArry[0], fileNameArry[1], fileNameArry[2], fileNameArry[3]);
            }
        });
        intervalStartWordTest();
    }


    /**
     * 获取Presenter，不用MVP，可以为空
     *
     * @return
     */
    @Override
    protected IBasePresenter onBasePresenter() {
        return null;
    }


    private void startRecoder(int recordTime, String recordFileName, String newwordId) {

        if (recordManager.getState() != RecordHelper.RecordState.STOP) {
            doRecodStop();
        }
        recordManager.start(recordFileName);

        startInverTime(recordTime);
    }


    private int getRecordTime(int second) {
        return second * 1000 / 100;
    }

    private void startInverTime(int second) {
        Observable.interval(100, TimeUnit.MILLISECONDS)
                .take(getRecordTime(second) + 2)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        GlideUtil.loadGif(R.mipmap.ic_recoding_audio, imgRecording);
                    }

                    @Override
                    public void onNext(Long aLong) {

                        float timeScale = (float) (aLong + 1) / (float) (getRecordTime(second) - 2 + 1);

                        int timeNum = (int) (timeScale * 100);


                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            recordBb.setProgress(timeNum, true);
                        } else {
                            recordBb.setProgress(timeNum);
                        }

                    }

                    @Override
                    public void onError(Throwable e) {
                    }

                    @Override
                    public void onComplete() {

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                            recordBb.setProgress(100, true);
                        } else {
                            recordBb.setProgress(100);
                        }

                        doRecodStop();
                    }
                });
    }

    public void setQuesName(String mQuesName) {
        this.mQuesName = mQuesName;
    }

    public void setUnitId(String mUnitId) {
        this.mUnitId = mUnitId;
    }

    private void doRecodStop() {
        recordManager.stop();
    }


    private int index = 0;

    private List<TestTrainDataBean> testTrainDataBeans;


    private List<TestTrainWordResultDataBean> testTrainResultDataBeans;

    private void intervalStartWordTest() {

        if (index >= testTrainDataBeans.size()) {
            showRecordWordCompleteView();
            return;
        }

        TestTrainDataBean testTrainDataBean = testTrainDataBeans.get(index);

        tvWords.setText(testTrainDataBean.getTitle());

        tvPy.setText(testTrainDataBean.getPinyin());


        if (index == 0) {
            Observable.timer(1, TimeUnit.SECONDS)
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Consumer<Long>() {
                        @Override
                        public void accept(Long aLong) throws Exception {
                            recordBb.setProgress(0);

                            startRecoder(testTrainDataBean.getTime(), getFileName(testTrainDataBean), testTrainDataBean.getNewwordid() + "");

                            index++;
                        }
                    });
        } else {
            recordBb.setProgress(0);

            startRecoder(testTrainDataBean.getTime(), getFileName(testTrainDataBean), testTrainDataBean.getNewwordid() + "");

            index++;
        }


    }


    private String getFileName(TestTrainDataBean testTrainDataBean) {
        String recodFileName = testTrainDataBean.getTitle() + "_" + testTrainDataBean.getPinyin() + "_" + testTrainDataBean.getNewwordid() + "_" + testTrainDataBean.getAssess_record_id() + "_" + testTrainDataBean.getTime();
        return recodFileName;
    }

    private void setCompleteResult() {
        HttpMethod.getIntence().getTestCompleteResult(mUnitId, new CustomObserver<BaseDataBean>(getContext()) {
            @Override
            public void onSuccess(BaseDataBean baseDataBean) {
                progressBar.setVisibility(View.GONE);
                TestWordRecordPopupWindow testWordRecordPopupWindow = new TestWordRecordPopupWindow(getActivity(), testTrainResultDataBeans, mQuesName);
                testWordRecordPopupWindow.showView();
            }

            @Override
            public void onError(String errorCode) {
                progressBar.setVisibility(View.GONE);
                TestWordRecordPopupWindow testWordRecordPopupWindow = new TestWordRecordPopupWindow(getActivity(), testTrainResultDataBeans, mQuesName);
                testWordRecordPopupWindow.showView();
            }
        });


    }

    public void setAiRecord(boolean aiRecord) {
        isAiRecord = aiRecord;
    }

    public void setGroupid(String mGroupid) {
        this.mGroupid = mGroupid;
    }


    public void setCategoryid(String mCategoryid) {
        this.mCategoryid = mCategoryid;
    }


    private void showRecordWordCompleteView() {


        cardContent.setVisibility(View.GONE);

        if (isAiRecord) {
            Observable.interval(200, TimeUnit.MILLISECONDS)
                    .takeUntil(new Predicate<Long>() {
                        @Override
                        public boolean test(Long aLong) throws Exception {
                            if (mAiTestUploadNum == testTrainDataBeans.size()) {
                                return true;
                            }
                            return false;
                        }
                    })
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(Long aLong) {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            setAiCompleteResult();
                        }
                    });
        } else {
            progressBar.setVisibility(View.VISIBLE);
            Observable.interval(200, TimeUnit.MILLISECONDS)
                    .takeUntil(new Predicate<Long>() {
                        @Override
                        public boolean test(Long aLong) throws Exception {

                            if (testTrainResultDataBeans.size() == testTrainDataBeans.size()) {
                                return true;
                            }
                            return false;
                        }
                    })
                    .subscribe(new Observer<Long>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                        }

                        @Override
                        public void onNext(Long aLong) {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            setCompleteResult();
                        }
                    });
        }


    }

    private void setAiCompleteResult() {

        showLoading();
        HttpMethod.getIntence().setAiCompleteResult(mGroupid, mCategoryid, new CustomObserver<BaseDataBean>(getContext()) {
            @Override
            public void onSuccess(BaseDataBean baseDataBean) {
                disLoading();
                TestWordRecordPopupWindow testWordRecordPopupWindow = new TestWordRecordPopupWindow(getActivity(), null, "");
                testWordRecordPopupWindow.showView();
            }

            @Override
            public void onError(String errorCode) {
                disLoading();
                ToastUtils.getIntence().makeTextShow("AI測試失敗，請聯系工作人員");
            }
        });

    }

    private void addDefaultTestResult(String pinyin, String title) {
        TestTrainWordResultDataBean testTrainWordResultDataBean = new TestTrainWordResultDataBean();
        testTrainWordResultDataBean.setPinyin(pinyin);
        testTrainWordResultDataBean.setWord(title);
        testTrainResultDataBeans.add(testTrainWordResultDataBean);
    }


    private void uploadRecordFile(String filePath, String title, String pinyin, String newwordid, String assess_record_id) {
        if (isAiRecord) {
            uploadAiTestFile(filePath, newwordid, assess_record_id);
        } else {
            uploadTestFile(filePath, title, pinyin, newwordid);
        }

    }


    /**
     * 上传AI录音文件
     *
     * @param filePath
     * @param newwordid
     * @param assess_record_id
     */
    private void uploadAiTestFile(String filePath, String newwordid, String assess_record_id) {
        Observable<BaseDataBean> observable = Observable.just(filePath)
                .flatMap((Function<String, ObservableSource<String>>) s -> {
                    File file = new File(filePath);
                    return Observable.just(BaseUtils.fileToBase64(file));
                })
                .flatMap((Function<String, ObservableSource<BaseDataBean>>) base64 -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("file64", base64);
                    map.put("newwordid", newwordid);
                    map.put("assess_record_id", assess_record_id);
                    return CustomApi.getIntence().getApi().uploadAiRecord(map);
                });

        observable.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<BaseDataBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(BaseDataBean baseDataBean) {
                        mAiTestUploadNum++;
                        FileUtils.delete(filePath);
                    }

                    @Override
                    public void onError(Throwable e) {
                        mAiTestUploadNum++;
                        e.printStackTrace();
                        FileUtils.delete(filePath);
                    }

                    @Override
                    public void onComplete() {
                    }
                });

    }


    /**
     * 上传测试录音文件
     *
     * @param filePath
     * @param newwordid
     */
    private void uploadTestFile(String filePath, String title, String pinyin, String newwordid) {
        if (testTrainResultDataBeans == null) {
            testTrainResultDataBeans = new ArrayList<>();
        }

        Observable<BaseDataBean<TestTrainWordResultDataBean>> observable = Observable.just(filePath)
                .flatMap((Function<String, ObservableSource<String>>) s -> {
                    File file = new File(filePath);

                    return Observable.just(BaseUtils.fileToBase64(file));
                })
                .flatMap((Function<String, ObservableSource<BaseDataBean<TestTrainWordResultDataBean>>>) base64 -> {
                    Map<String, String> map = new HashMap<>();
                    map.put("file64", base64);
                    map.put("newwordid", newwordid);
                    return CustomApi.getIntence().getApi().uploadTestRecord(map);
                });

        observable.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<BaseDataBean<TestTrainWordResultDataBean>>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(BaseDataBean<TestTrainWordResultDataBean> baseDataBean) {
                        if (baseDataBean.getCode() == 200 && baseDataBean.getData() != null) {
                            Log.i("filePath", newwordid + "filePath:" + filePath);
                            testTrainResultDataBeans.add(baseDataBean.getData());
                        } else {
                            addDefaultTestResult(pinyin, title);
                        }

                        FileUtils.delete(filePath);
                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();
                        addDefaultTestResult(pinyin, title);
                        FileUtils.delete(filePath);
                    }

                    @Override
                    public void onComplete() {
                    }
                });

    }

}
